#include<iostream>
#include<vector>
#include<cstdint>
#include<cassert>
#include<cstring>
#include<string>
const static int BUFFER_DEFAULT_SIZE = 1024;
class Buffer
{
public:
    Buffer()
    :_buffer(BUFFER_DEFAULT_SIZE),
    _reader_idx(0),
    _writer_idx(0)
    {

    }
    ~Buffer(){}
    //缓冲区初始位置
    char* Begin(){return &*_buffer.begin();}
    //获取当前写位置
    char* WritePosition()
    {
        return Begin()+_writer_idx;
    }
    //获取当前读位置
    char* ReadPosition()
    {
        return Begin()+_reader_idx;
    }
    //获取缓冲区末尾空闲大小--写位置之后
    uint64_t TailIdlSize(){return _buffer.size() - _writer_idx;}
    //获取缓冲区开头空闲大小--读位置之前
    uint64_t HeadIdlSize(){return _reader_idx;}
    //获取可读空间大小
    uint64_t ReadAbleSize(){return _writer_idx - _reader_idx;}
    //读指针向后偏移
    void MoveReadOffset(uint64_t len)
    {
        if(len == 0) return;
        assert(len <= ReadAbleSize());
        _reader_idx += len;
    }
    //写指针向后偏移
    void MoveWriteOffset(uint64_t len)
    {
        if(len == 0) return;
        assert(len <= TailIdlSize());
        _writer_idx += len;
    }
    //确保可写空间足够（移动/扩容）
    void EnsureWriteAble(uint64_t len)
    {
        //可以直接在末尾写
        if(len <= TailIdlSize()) return;
        //前后空间足够--移动
        if(len <= TailIdlSize()+HeadIdlSize())
        {
            uint64_t rsz = ReadAbleSize();//记录当前可读大小
            std::copy(ReadPosition(),ReadPosition()+rsz,Begin());
            //移动读写指针
            _reader_idx = 0;
            _writer_idx = rsz;
        }
        //不够--扩容
        else{
            uint64_t rsz = ReadAbleSize();//记录当前可读大小
            _buffer.resize(_writer_idx + rsz);
              //移动读写指针
            _reader_idx = 0;
            _writer_idx = rsz;
        }
    }
    //写入数据
    void Write(const void* data,uint64_t len)
    {
        assert(len > 0);
        EnsureWriteAble(len);
        char* d = (char*)data;
        std::copy(d,d+len,WritePosition());
    }
    //写入数据并移动
    void WriteAndPush(void* data,uint64_t len)
    {
        Write(data,len);
        MoveWriteOffset(len);
    }
    //写入一个字符串
    void WriteString(const std::string& str)
    {
        Write(str.c_str(),str.size());
    }
    void WriteStringAndPush(const std::string& str)
    {
        WriteString(str);
        MoveWriteOffset(str.size());
    }
    //写入另一个Buffer
    void WriteBuffer(Buffer& buffer)
    {
        Write(buffer.ReadPosition(),buffer.ReadAbleSize());
    }
    void WriteBufferAndPush(Buffer& buffer)
    {
        Write(buffer.ReadPosition(),buffer.ReadAbleSize());
        MoveWriteOffset(buffer.ReadAbleSize());
    }
    //读取数据
    void Read(void* buffer,uint64_t len)
    {
        assert(len > 0);
        assert(len <= ReadAbleSize());
        std::copy(ReadPosition(),ReadPosition()+len,(char*)buffer);
    }
    void ReadAndPop(void* buffer,uint64_t len)
    {
        Read(buffer,len);
        MoveReadOffset(len);
    }
    //读取到的数据当作string返回
    std::string ReadAsString(uint64_t len)
    {
        assert(len > 0 && len <= ReadAbleSize());
        std::string ret;
        ret.resize(len);
        Read(&ret[0],len);
        return ret;
    }
    std::string ReadAsStringAndPop(uint64_t len)
    {
        assert(len > 0 && len <= ReadAbleSize());
        std::string ret = ReadAsString(len);
        MoveReadOffset(len);
        return ret;
    }

    //寻找换行
    char* FindCRLF()
    {
        char* ret = (char*)memchr(ReadPosition(),'\n',ReadAbleSize());
        return ret;
    }
    //获取一行
    // std::string GetLine()
    // {
    //     char* ret = FindCRLF();
    //     if(ret == NULL) return "";
    //     uint64_t len = ret - ReadPosition();
    //     std::string str;
    //     str.resize(len);
    //     std::copy(ReadPosition(),ret+1,&str[0]);
    //     return str;
    // }
    std::string GetLine()
    {
        char* ret = FindCRLF();
        if(ret == NULL) return "";
        //把\n也取出来
        return ReadAsString(ret - ReadPosition() + 1);
    }
    std::string GetLineAndPop()
    {
        char* ret = FindCRLF();
        if(ret == NULL) return "";
        std::string str = ReadAsString(ret - ReadPosition() + 1); 
        MoveReadOffset(str.size());
        return str;
    } 
    //清空缓冲区
    void Clear()
    {
        _reader_idx = _writer_idx = 0;
    }
        




private:
    std::vector<char> _buffer;
    uint64_t _reader_idx;
    uint64_t _writer_idx;


};